package com.haoran.dwz.domain.entities;

import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.springframework.util.Assert;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import io.swagger.annotations.ApiModel;

/**
 * 系统菜单 子节点维护与父节点的关系
 * 
 * @author Administrator
 *
 */
@Entity
@Table(name = "t_menu")
@ApiModel("系统菜单")
public class Menu extends AbstractEntity {
	
	/**
	 * 编码前缀
	 */
	public static String PREFIX_OF_NUMBER = "menu_";

	private static final long serialVersionUID = 1L;

	/**
	 * 菜单名称
	 */
	@Column(precision = 1)
	private String name;
	
	@Column(precision = 2)
	private String url;

	@Column(precision = 3)
	private String permission;

	@Column(precision = 4)
	private String icon;

	/**
	 * ztree属性
	 */
	@Column(precision = 5)
	private Boolean open;

	@Enumerated(javax.persistence.EnumType.STRING)
	private Target target;
	
//	@JsonBackReference  
//	@JsonIgnore
//	@ApiModelProperty(hidden=true)
//    @ManyToMany(mappedBy = "menus", fetch = FetchType.EAGER)
//    private Set<Role> roles = new HashSet<Role>();
//	public Set<Role> getRoles() {
//		return roles;
//	}
//
//	public void setRoles(Set<Role> roles) {
//		this.roles = roles;
//	}

	/**
	 * 排序
	 */
	@Column(precision = 6, name = "f_order")
	private Integer orderNumber;

	@Column(precision = 7)
	private String number;
	/**
	 * 父菜单ID，一级菜单为NULL 子节点维护与父节点的关系
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "parent_id", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
	@JsonBackReference
	private Menu parent;

	@SuppressWarnings("deprecation")
	@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", orphanRemoval = true)
	@JsonManagedReference
	@org.hibernate.annotations.ForeignKey(name = "none")
	private Collection<Menu> children = new HashSet<Menu>(0);

	public Menu getParent() {
		return parent;
	}

	public void setParent(Menu parent) {
		this.parent = parent;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getPermission() {
		return permission;
	}

	public void setPermission(String permission) {
		this.permission = permission;
	}

	public String getIcon() {
		return icon;
	}

	public void setIcon(String icon) {
		this.icon = icon;
	}

	public Integer getOrderNumber() {
		return orderNumber;
	}

	public void setOrderNumber(Integer orderNumber) {
		this.orderNumber = orderNumber;
	}

	public Boolean getOpen() {
		return open;
	}

	public void setOpen(Boolean open) {
		this.open = open;
	}

	public Target getTarget() {
		return target;
	}

	public void setTarget(Target target) {
		this.target = target;
	}

	public Collection<Menu> getChildren() {
		return children;
	}

	public void setChildren(Collection<Menu> children) {
		this.children = children;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public static SortedSet<Menu> sort(Collection<Menu> menus) {
		Assert.notNull(menus, "Cannot pass a null Menu collection");
		SortedSet<Menu> sortedAuthorities = new TreeSet<Menu>(new MenuComparator());
		for (Menu role : menus) {
			sortedAuthorities.add(role);
		}
		return sortedAuthorities;
	}

	private static class MenuComparator implements Comparator<Menu>, Serializable {

		private static final long serialVersionUID = 8795672889281603780L;

		@Override
		public int compare(Menu o1, Menu o2) {
			return o1.getOrderNumber().equals(o2.getOrderNumber()) ?  o1.getId().compareTo(o2.getId()) : o1.getOrderNumber().compareTo(o2.getOrderNumber());
		}
	}
	
	public static enum Target {
		main_frame,
		_blank,
		_parent,
		_self,
		_top
	}
}
